<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\Models\SyUser;
use App\Models\Phpwarn;
use App\Models\Scope\CompanyScope;
use App\Models\Area;
use App\Http\traits\Utils;

class NewWarn implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels, Utils;
    
    public $user;
    

    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(SyUser $user)
    {
        $this->user = $user;
    }

    private function getWarns() {
       $cid = $this->user->Co_ID;
       return Phpwarn::withoutGlobalScope(CompanyScope::class)
               ->company($cid)
               ->select(['pdi_devid', 'pdi_name', 'pdi_typememo', 'pdi_warnlevel', 'pdi_warnname', 'pdi_updatetime', 'pdi_areaid', 'pdi_areaname'])
               ->orderBy('pdi_updatetime', 'desc')
               ->limit(5)
               ->get();
    }
    
    //告警统计
    private function getWarnsStatisc() {
        $fields = [
            'pdi_devid', 'pdi_name', 'pdi_typememo', 'pdi_warnlevel', 
            'pdi_warnname', 'pdi_updatetime', 'pdi_areaid', 'pdi_areaname',
            'pdi_warnlevel'
        ];
        $cid = $this->user->Co_ID;
        $lists = Phpwarn::withoutGlobalScope(CompanyScope::class)
               ->company($cid)
                ->select($fields)
                ->orderBy('pdi_updatetime', 'desc')
                ->get();
        
        $warnTotal = $lists->count();
        
        $warnNew = $lists->take(5);
        
        $warnStatiscByTime = $lists->groupBy(function($item){ 
           return substr($item['pdi_updatetime'], 0, 10);
        })->map(function($item, $key){
            return ['warn_num'=>count($item), 'date'=>$key];
        })->sortBy('date')->values();
        
        $warnStatiscByLevel = $lists->groupBy('pdi_warnlevel')->map(function($item, $key){
            $config = config('device.warn_level');
            return [ 'lvl' => array_get($config, $key.'.name'), 'num' => count($item), 'plvl'=>$key];
        })->sortBy('plvl')->values();
        
        $warnException = $lists->groupBy('pdi_devid')->map(function($item, $key){
            return ['exception'=>count($item), 'normal'=>0, 'device'=>$key];
        })->values();
        
        $areaWarns = $lists->groupBy('pdi_areaid')->map(function($item){
            return count($item);
        });
        
        $parentArea = Area::withoutGlobalScope(CompanyScope::class)
                ->company($cid)
                ->select(['AreaId', 'Fid', 'AreaName', 'lnglat', 'area_code'])
                ->get()
                ->toArray();
        
        $areas = $this->listToTree($parentArea, 'AreaId', 'Fid');
        
        $areasGroup = collect($areas)->map(function($item)use($areaWarns){
            $children = $item['children'];
            $total = 0;
            foreach ($children as  &$v) {
                $num = array_get($areaWarns, $v['AreaId'], 0);
                $total += $num;
                $v['total'] = $num;
            }
            $item['children'] = $children;
            $item['total'] = $total;
            return $item;
        });

        
        return compact('warnStatiscByLevel', 'warnStatiscByTime',  'warnTotal', 'warnNew', 'warnException', 'areasGroup');
    }
    
    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('team.'.$this->user->Co_ID);
    }
    
    public function broadcastWith()
    {
        return [
            'warns' => $this->getWarnsStatisc()
        ];
    }
}
